﻿using AdminManager.System.OrganizationUnits;
using AdminManager.System.User;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Identity;

namespace AdminManager.System
{
    [Authorize(IdentityPermissions.Users.Default)]
    public class UserExtenAppService : ApplicationService, IUserExtenAppService
    {
        private readonly IdentityUserManager _identityUserManager;
        private readonly IRepository<OrganizationUnit> _organizaitonUnitRepository;
        private readonly IRepository<IdentityUserOrganizationUnit> _identityUserOrganizationUnitRepository;
        private readonly ILogger<UserExtenAppService> _logger;
        public UserExtenAppService(IdentityUserManager identityUserManager, IRepository<OrganizationUnit> organizaitonUnitRepository,
            IRepository<IdentityUserOrganizationUnit> identityUserOrganizationUnitRepository, ILogger<UserExtenAppService> logger)
        {
            this._identityUserManager = identityUserManager;
            this._organizaitonUnitRepository = organizaitonUnitRepository;
            this._identityUserOrganizationUnitRepository = identityUserOrganizationUnitRepository;
            this._logger = logger;
        }

        public async Task<OrganizationUserDto> GetDeptsByUidAsync(string uid)
        {
            IdentityUserOrganizationUnit item = await this._identityUserOrganizationUnitRepository.FirstAsync(p => p.UserId == Guid.Parse(uid));
            return ObjectMapper.Map<IdentityUserOrganizationUnit, OrganizationUserDto>(item);
        }

        public  async Task<PagedResultDto<IdentityUserDto>> GetUsersAsync(UserSearchDto searchDto)
        {
            OrganizationUnit organization = null;
            if (string.IsNullOrEmpty(searchDto.DeptId))
            {
                organization = await this._organizaitonUnitRepository.FirstOrDefaultAsync(p => p.ParentId == null);
            }
            else
            {
                organization = await this._organizaitonUnitRepository.FirstOrDefaultAsync(p => p.Id == Guid.Parse(searchDto.DeptId));
            }
            if (organization == null)
            {
                throw new BusinessException(AdminManagerDomainErrorCodes.NotFoundData);
            }
            List<IdentityUser> userlist = await _identityUserManager.GetUsersInOrganizationUnitAsync(organization, true);
            if (!string.IsNullOrWhiteSpace(searchDto.UserName))
            {
                userlist = userlist.Where(p => p.UserName.Contains(searchDto.UserName.Trim())).ToList();
            }
            userlist = userlist.Skip(searchDto.SkipCount - 1)
                .Take(searchDto.MaxResultCount)
                .OrderByDescending(p=>p.CreationTime)
                .ToList();
            return new PagedResultDto<IdentityUserDto>(userlist.Count, ObjectMapper.Map<List<IdentityUser>, List<IdentityUserDto>>(userlist));
        }

        [Authorize(IdentityPermissions.Users.Update)]
        public async Task<string> UpdateUsersPwdAsync(UserPwdInputDto inputDto)
        {
            if (!inputDto.NewPwd.Equals(inputDto.ConfirmPwd))
            {
                throw new BusinessException(IdentityErrorCodes.ExternalUserPasswordChange);
            }
            var user = await _identityUserManager.GetByIdAsync((Guid)CurrentUser.Id);
            Microsoft.AspNetCore.Identity.IdentityResult identityResult = await  _identityUserManager.ChangePasswordAsync(user, inputDto.OldPwd, inputDto.NewPwd);
            if (identityResult.Succeeded)
            {

                return "修改成功";
            }
            else
            {
                string errormsg = "";
                foreach (var item in identityResult.Errors)
                {
                    errormsg = item.Code + " " + item.Description + "|";
                }
                throw new AbpException(errormsg); 
            }
        }
    }
}
